#include "newsserver.h"

using namespace std;
using namespace client_server;

newsserver::newsserver(database_interface *db, int in_port) : dbp(db), port(in_port), server(in_port) {}

newsserver::~newsserver(){}

void newsserver::run(){
    if (! server.isReady()) {
        cerr << "Server initialization error" << endl;
        exit(1);
    }
	cout << "server running on port " << port << endl;

	while (true) {
		Connection* conn = server.waitForActivity();
		if (conn != 0) {
		    try {
		        char cmd = mh.identify(conn); //fetch command byte from client
		       if(cmd == protocol::Protocol::COM_LIST_NG){
		        	vector<pair<unsigned int, string> > v;
		        	v = dbp->get_newsgroups();
		        	mh.ans_list_groups(conn, v);
		        
		        } else if(cmd == protocol::Protocol::COM_CREATE_NG) {
		        	// (COM_CREATE_NG) string_p COM_END
		        	string s = mh.read_string(conn);
		        	bool created = dbp->create_newsgroup(s);
		        	mh.ans_create_group(conn, created);
		        	
		        } else if(cmd == protocol::Protocol::COM_DELETE_NG) {
		        	// (COM_DELETE_NG) num_p COM_END
		        	unsigned int id = mh.read_uint(conn);
		        	bool removed = dbp->remove_newsgroup(id);
				mh.ans_delete_group(conn, removed);
		        } else if(cmd == protocol::Protocol::COM_LIST_ART) {
				int p = mh.read_uint(conn);
				vector <pair<unsigned int, string> > v = dbp->get_news_entries(p);
				mh.ans_list_art(conn, v);
				
		        } else if(cmd == protocol::Protocol::COM_CREATE_ART) {
				int p = mh.read_uint(conn);
				string title = mh.read_string(conn);
				string author = mh.read_string(conn);
				string text = mh.read_string(conn);
				bool created = dbp->put(p, title, author, text).first;
				mh.ans_create_art(conn, created);
		        } else if(cmd == protocol::Protocol::COM_DELETE_ART) {
				unsigned int g_id = mh.read_uint(conn);
				unsigned int a_id = mh.read_uint(conn);
				int status = dbp->remove(g_id, a_id);
				mh.ans_delete_art(conn, status);
		        } else if(cmd == protocol::Protocol::COM_GET_ART) {
				unsigned int g_id = mh.read_uint(conn);
				unsigned int a_id = mh.read_uint(conn);
				pair<int, map<string, string> > article = dbp->get(g_id, a_id);
				mh.ans_get_art(conn, article);
				
		        } 
			//läs
			//parsa
			//skriv data
		    }
		    catch (ConnectionClosedException&) {
		        server.deregisterConnection(conn);
		        delete conn;
		        cout << "Client closed connection" << endl;
		    }
		    
		    catch(ProtocolException& e){
		    	server.deregisterConnection(conn);
		        delete conn;
		        cout << "<< Protocol breach >>" << endl << "function: " << e.fcn << endl <<
		        	"recieved: " << static_cast<int>(e.rec) << endl << "reference: " <<
		        	static_cast<int>(e.ref) << endl << "Kicking client..." << endl;
		    }
		}
		else {
		    server.registerConnection(new Connection);
		    cout << "New client connects" << endl;
		}
    }
}


/*
int main(){
	#ifdef DRIVEDB
		drivedatabase *p = new drivedatabase();
	#endif

	#ifdef MEMDB
		memdatabase *p = new memdatabase();
	#endif

	newsserver n(p);
	n.run();
	delete(p);
}

*/
